<h3>Chapter 4: Functions</h3>
<p><strong>Review</strong></p>
<p>
By this point, you should be aware that LPC objects
consist of functions which manipulate variables.
The functions manipulate variables when they are executed, and
they get executed through <B>calls </B>to those functions.
</p>
<p>
The order in which the functions are placed in a
file does not matter. Inside a function, the variables get manipulated.
They are stored in computer memory and used by the computer as
0's and 1's which get translated to and from useable output and
input through a device called data typing. String data types tell
the driver that the data should appear to you and come from you
in the form of alphanumeric characters. Variables of type int
are represented to you as whole number values. Type status is
represented to you as either 1 or 0. And finally type void has
no value to you or the machine, and is not really used with variable
data types.
</p>
<hr size="1">
<p><strong>What is a function?</strong></p>
<p>
Like math functions, LPC functions take input and
return output. Languages like Pascal distinguish
between the concept of procedure and the concept of function.
LPC does not, however, it is useful to understand this distinction.
What Pascal calls a procedure, LPC calls a
function of type void. In other words, a procedure, or function
of type void returns no output. What Pascal calls a function differs
in that it does return output. In LPC, the most trivial,
correct function is:
<pre>
void do_nothing() { }
</pre>
This function accepts no input, performs no instructions,
and returns no value.
</p>
<p>
There are three parts to every properly written LPC
function:
<ol>
<li>The declaration
<li>The definition
<li>The call
</ol>
Like with variables, functions must be declared.
This will allow the driver to know 1) what type of data the function
is returning as output, and 2) how many input(s) and of what type
those input(s) are. The more common word for
input is parameters.
</p>
<p>
A function declaration therefore consists of: type
name(parameter1, parameter2, ..., parameterN); The
declaration of a function called drink_water() which accepts a
string as input and an int as output would thus look like this:
<pre>
int drink_water( string str );
</pre>
where str is the name of the input as it will be
used inside the function.
</p>
<p>
The function definition is the code which describes
what the function actually does with the input
sent to it.
</p>
<p>
The call is any place in other functions which invokes
the execution of the function in question. For two functions write_vals()
and add(), you thus might have the following bit of code:
<pre>
/* First, function declarations. They usually appear at the beginning of
   object code. */
void write_vals();
int add( int x, int y );

/* Next, the definition of the function write_vals(). We assume that
   this function is going to be called from outside the object */
void write_vals() {
  int x;

  /* Now we assign x the value of the output of add() through a call */
  x = add( 2, 2 );
  write( x+&quot;\n&quot;);
}

/* Finally, the definition of add() */
int add( int x, int y ) {
  return ( x + y );
}
</pre>
Remember, it does not matter which function definition
appears first in the code. This is because
functions are not executed consecutively. Instead, functions are
executed as called. The only requirement is that the declaration
of a function appear before its definition and before the definition
of any function which makes a call to it.
</p>
<hr size="1">
<p><strong>Efuns</strong></p>
<p>
Perhaps you have heard people refer to efuns. They are externally defined
functions. Namely, they are defined by the mud driver. If you have played
around at all with coding in LPC, you have probably found some expressions
you were told to use like this_player(), write(), say(), this_object(),
etc. look a lot like functions. That is because they are efuns.
The value of efuns is that they are much faster than LPC functions,
since they already exist in the binary form the computer understands.
</p>
<p>
In the function write_vals() above, two functions
calls were made. The first was to the functions add(), which you
declared and defined. The second call, however, was to a function
called write(), and efun. The driver has already declared and
defined this function for you. You needs only to make calls to it.
</p>
<p>
Efuns are created to handle common, every day function
calls, to handle input/output to the internet
sockets, and other matters difficult to be dealt with in LPC.
They are written in C in the game driver and compiled along with
the driver before the mud comes up, making them much faster
in execution. But for your purposes, efun calls are
just like calls made to your functions. Still, it is important
to know two things of any efun: 1) what return
type does it have, and 2) what parameters of what types
does it take.
</p>
<p>
Information on efuns such as input parameters and
return types is often found in a directory called /doc/efun on
your mud. I cannot detail efuns here, because efuns vary from
driver to driver. However, you can often access
this information using the commands &quot;man&quot; or &quot;help&quot;
depending on your mudlib. For instance, the command &quot;man
write&quot; would give you information on the write efun. But
if all else fails, &quot;more /doc/efun/write&quot;
should work.
</p>
<p>
By looking it up, you will find write is declared as follows:
<pre>
void write(string);
</pre>
This tells you an appropriate call to write expects
no return value and passes a single parameter
of type string.
</p>
<hr size="1">
<p><strong>Defining your own functions</strong></p>
<p>
Although ordering your functions within the file
does not matter, ordering the code which defines a function is
most important. Once a function has been called, function code
is executed in the order it appears in the
function definition. In write_vals() above, the instruction:
<pre>
x = add( 2, 2 );
</pre>
Must come before the write() efun call if you want
to see the appropriate value of x used in write().
</p>
<p>
With respect to values returned by function, this
is done through the &quot;return&quot; instruction followed by
a value of the same data type as the function. In add() above,
the instruction is &quot;return (x+y);&quot;, where the value
of (x+y) is the value returned to write_vals() and assigned to
x. On a more general level, &quot;return&quot;
halts the execution of a function and returns code execution to
the function which called that function. In addition, it returns
to the calling function the value of any expression that follows.
</p>
<p>
To stop the execution of a function of type void
out of order, use &quot;return&quot;; without any value following.
Once again, remember, the data type of the value of any expression
returned using &quot;return&quot; MUST be the same
as the data type of the function itself.
</p>
<hr size="1">
<p><strong>Chapter Summary</strong></p>
<p>
The files which define LPC objects are made of of
functions. Functions, in turn, are made up of three parts:
<ol>
<li>The declaration
<li>The definition
<li>The call
</ol>
Function declarations generally appear at the top
of the file before any definitions, although the requirement is
that the declaration must appear before the function definition
and before the definition of any function which
calls it.
</p>
<p>
Function definitions may appear in the file in any
order so long as they come after their declaration.
In addition, you may not define one function inside another function.
</p>
<p>
Function calls appear inside the definition of other
functions where you want the code to begin execution of your function.
They may also appear within the definition of the function itself,
but this is not recommended for new coders,
as it can easily lead to infinite loops.
</p>
<p>
The function definition consists of the following in this order:
<ol>
<li>function return type
<li>function name
<li>opening ( followed by a parameter list and a closing )
<li>an opening { instructing the driver that execution begins here
<li>declarations of any variables to be used only in that function
<li>instructions, expressions, and calls to other functions as needed
<li>a closing } stating that the function code ends here and,
if no &quot;return&quot; instruction has been given at this point
(type void functions only), execution returns to the calling function
as if a r&quot;return&quot; instruction was given
</ol>
The trivial function would thus be:
<pre>
void do_nothing() {}
</pre>
since this function does not accept any input, perform
any instructions, or return any output.
</p>
<p>
Any function which is not of type void MUST return
a value of a data type matching the function's
data type.
</p>
<p>
Each driver has a set of functions already defined
for you called efuns These you need neither need to declare nor
define since it has already been done for you. Furthermore, execution
of these functions is faster than the execution
of your functions since efuns are in the driver.
</p>
<p>
In addition, each mudlib has special functions like
efuns in that they are already defined and declared for you, but
different in that they are defined in the mudlib and in LPC. They
are called simul_efuns, or simulated efuns.
You can find out all about each of these as they are listed in
the /doc/efun directory on most muds. In addition many muds have
a command called &quot;man&quot; or a &quot;help&quot; command
which allows you simply to call up the info
files on them.
</p>
<p>
Note on style:
<blockquote>
Some drivers may not require you to declare your functions, and some
may not require you to specify the return type of the function in its
definition. Regardless of this fact, you should never omit this information
for the following reasons:
<ol>
<li>It is easier for other people (and you at later dates) to
read your code and understand what is meant. This is particularly
useful for debugging, where a large portion of errors (outside
of misplaced parentheses and brackets) involve problems with data
types (Ever gotten &quot;Bad arg 1 to foo() line 32&quot;?).
<li>It is simply considered good coding form.
</ol>
</blockquote>
</p>
